{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cellView": "form",
    "id": "KQa9t_gadIuR"
   },
   "outputs": [],
   "source": [
    "# @title Copyright 2022 The Cirq Developers\n",
    "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "# https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "xwec7FrkdFmi"
   },
   "source": [
    "# Gate Zoo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "5KZia7jmdJ3V"
   },
   "source": [
    "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://quantumai.google/cirq/gatezoo.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/quantumai_logo_1x.png\" />View on QuantumAI</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/quantumlib/Cirq/blob/main/docs/gatezoo.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/colab_logo_1x.png\" />Run in Google Colab</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a target=\"_blank\" href=\"https://github.com/quantumlib/Cirq/blob/main/docs/gatezoo.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/github_logo_1x.png\" />View source on GitHub</a>\n",
    "  </td>\n",
    "  <td>\n",
    "    <a href=\"https://storage.googleapis.com/tensorflow_docs/Cirq/docs/gatezoo.ipynb\"><img src=\"https://quantumai.google/site-assets/images/buttons/download_icon_1x.png\" />Download notebook</a>\n",
    "  </td>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "541571c2edcd"
   },
   "source": [
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "bd9529db1c0b"
   },
   "outputs": [],
   "source": [
    "try:\n",
    "    import cirq\n",
    "except ImportError:\n",
    "    print(\"installing cirq...\")\n",
    "    !pip install --quiet cirq\n",
    "    print(\"installed cirq.\")\n",
    "\n",
    "import IPython.display as ipd\n",
    "import cirq\n",
    "import inspect\n",
    "\n",
    "\n",
    "def display_gates(*gates):\n",
    "    for gate_name in gates:\n",
    "        ipd.display(ipd.Markdown(\"---\"))\n",
    "        gate = getattr(cirq, gate_name)\n",
    "        ipd.display(ipd.Markdown(f\"#### cirq.{gate_name}\"))\n",
    "        ipd.display(ipd.Markdown(inspect.cleandoc(gate.__doc__ or \"\")))\n",
    "    else:\n",
    "        ipd.display(ipd.Markdown(\"---\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1cd004cc2f3a"
   },
   "source": [
    "Cirq comes with many gates that are standard across quantum computing. This notebook serves as a reference sheet for these gates.\n",
    "\n",
    "## Single Qubit Gates\n",
    "\n",
    "\n",
    "### Gate Constants \n",
    "\n",
    "Cirq defines constants which are gate instances for particular important single qubit gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "0c3a029e2155"
   },
   "outputs": [],
   "source": [
    "display_gates(\"X\", \"Y\", \"Z\", \"H\", \"S\", \"T\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "10c855370f45"
   },
   "source": [
    "### Traditional Pauli Rotation Gates\n",
    "\n",
    "Cirq defines traditional single qubit rotations that are rotations in radiants abougt different Pauli directions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "e96e1c459258"
   },
   "outputs": [],
   "source": [
    "display_gates(\"Rx\", \"Ry\", \"Rz\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "4bfc17ef80bb"
   },
   "source": [
    "### Pauli PowGates\n",
    "\n",
    "If you think of the `cirq.Z` gate as phasing the state $|1\\rangle$ by $-1$, then you might think that the square root of this gate phases the state $|1\\rangle$ by $i=\\sqrt{-1}$.  The `XPowGate`, `YPowGate` and `ZPowGate`s all act in this manner, phasing the state corresponding to their $-1$ eigenvalue by a prescribed amount.  This ends up being the same as the `Rx`, `Ry`, and `Rz` up to a global phase."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "0e2ea8a0a0ae"
   },
   "outputs": [],
   "source": [
    "display_gates(\"XPowGate\", \"YPowGate\", \"ZPowGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "6631a361ac42"
   },
   "source": [
    "### More Single Qubit Gate\n",
    "\n",
    "Many quantum computing implementations use qubits whose energy eigenstate are the computational basis states. In these cases it is often useful to move `cirq.ZPowGate`'s through other single qubit gates, \"phasing\" the other gates.  For these scenarios, the following phased gates are useful."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "b5ffeefa3c76"
   },
   "outputs": [],
   "source": [
    "display_gates(\"PhasedXPowGate\", \"PhasedXZGate\", \"HPowGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "3a2c64c91b88"
   },
   "source": [
    "## Two Qubit Gates\n",
    "\n",
    "### Gate Constants\n",
    "\n",
    "Cirq defines convenient constants for common two qubit gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "c964adb80c40"
   },
   "outputs": [],
   "source": [
    "display_gates(\"CX\", \"CZ\", \"SWAP\", \"ISWAP\", \"ISWAP_INV\", \"SQRT_ISWAP\", \"SQRT_ISWAP_INV\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "900df682eac9"
   },
   "source": [
    "### Parity Gates\n",
    "\n",
    "If $P$ is a non-identity Pauli matrix, then it has eigenvalues $\\pm 1$.  $P \\otimes P$ similarly has eigenvalues $\\pm 1$ which are the product of the eigenvalues of the single $P$ eigenvalues. In this sense, $P \\otimes P$ has an eigenvalue which encodes the parity of the eigenvalues of the two qubits.  If you think of $P \\otimes P$ as phasing its $-1$ eigenvectors by $-1$, then you could consider $(P \\otimes P)^{\\frac{1}{2}}$ as the gate that phases the $-1$ eigenvectors by $\\sqrt{-1} =i$.  The Parity gates are exactly these gates for the three different non-identity Paulis. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3eb331e1369d"
   },
   "outputs": [],
   "source": [
    "display_gates(\"XXPowGate\", \"YYPowGate\", \"ZZPowGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "ce06c9c4af09"
   },
   "source": [
    "There are also constants that one can use to define the parity gates via exponentiating them."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "f4d5b06fe14f"
   },
   "outputs": [],
   "source": [
    "display_gates(\"XX\", \"YY\", \"ZZ\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7018ad92af8a"
   },
   "source": [
    "### Fermionic Gates\n",
    "\n",
    "If we think of $|1\\rangle$ as an excitation, then the gates that preserve the number of excitations are the fermionic gates.  There are two implementations, with differing phase conventions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "fcba4202211b"
   },
   "outputs": [],
   "source": [
    "display_gates(\"FSimGate\", \"PhasedFSimGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "921c70a620ec"
   },
   "source": [
    "### Two qubit PowGates\n",
    "\n",
    "Just as `cirq.XPowGate` represents a powering of `cirq.X`, our two qubit gate constants also have corresponding \"Pow\" versions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "492accb5827e"
   },
   "outputs": [],
   "source": [
    "display_gates(\"SwapPowGate\", \"ISwapPowGate\", \"CZPowGate\", \"CXPowGate\", \"PhasedISwapPowGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "c02cf4d59d01"
   },
   "source": [
    "## Three Qubit Gates\n",
    "\n",
    "### Gate Constants\n",
    "\n",
    "Cirq provides constants for common three qubit gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "7ceda5b42e82"
   },
   "outputs": [],
   "source": [
    "display_gates(\"CCX\", \"CCZ\", \"CSWAP\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "8c731a5d0e51"
   },
   "source": [
    "### Three Qubit Pow Gates\n",
    "\n",
    "Corresponding to some of the above gate constants are the corresponding PowGates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "3de3b125d41c"
   },
   "outputs": [],
   "source": [
    "display_gates(\"CCXPowGate\", \"CCZPowGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "1f05b8d50eae"
   },
   "source": [
    "## N Qubit Gates\n",
    "\n",
    "### Do Nothing Gates\n",
    "\n",
    "Sometimes you just want a gate to represent doing nothing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "9bff9fe0f592"
   },
   "outputs": [],
   "source": [
    "display_gates(\"IdentityGate\", \"WaitGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "49c9543253c7"
   },
   "source": [
    "### Measurement Gates\n",
    "\n",
    "Measurement gates are gates that represent a measurement and can operate on any number of qubits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "d8ad747875a8"
   },
   "outputs": [],
   "source": [
    "display_gates(\"MeasurementGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "fba13da22109"
   },
   "source": [
    "### Matrix Gates\n",
    "\n",
    "If one has a specific unitary matrix in mind, then one can construct it using matrix gates, or, if the unitary is diagonal, the diagonal gates."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "05a4209d7313"
   },
   "outputs": [],
   "source": [
    "display_gates(\"MatrixGate\", \"DiagonalGate\", \"TwoQubitDiagonalGate\", \"ThreeQubitDiagonalGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "12407f46f859"
   },
   "source": [
    "### Pauli String Gates\n",
    "\n",
    "Pauli strings are expressions like \"XXZ\" representing the Pauli operator X operating on the first two qubits, and Z on the last qubit, along with a numeric (or symbolic) coefficient. When the coefficient is a unit complex number, then this is a valid unitary gate.  Similarly one can construct gates which phases the $\\pm 1$ eigenvalues of such a Pauli string."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "4e901520caf3"
   },
   "outputs": [],
   "source": [
    "display_gates(\"DensePauliString\", \"MutableDensePauliString\", \"PauliStringPhasorGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "7be674562875"
   },
   "source": [
    "### Algorithm Based Gates\n",
    "\n",
    "It is useful to define composite gates which correspond to algorithmic primitives, i.e. one can think of the fourier transform as a single unitary gate."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "ccad5e95edcc"
   },
   "outputs": [],
   "source": [
    "display_gates(\"BooleanHamiltonianGate\", \"QuantumFourierTransformGate\", \"PhaseGradientGate\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "id": "001da7020514"
   },
   "source": [
    "### Classiscal Permutation Gates\n",
    "\n",
    "Sometimes you want to represent shuffling of qubits. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "id": "2804cdd9c98c"
   },
   "outputs": [],
   "source": [
    "display_gates(\"QubitPermutationGate\")"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "gatezoo.ipynb",
   "toc_visible": true
  },
  "kernelspec": {
   "display_name": "Python 3",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
